<template>
  <div class="dynamic-container">
    <el-table
      v-if="(listData && listData.length) || isEdit || showTableHeader"
      ref="dynamicEditRef"
      :data="handleData(listData)"
      :border="hasBorder"
      :empty-text="emptyText"
      :max-height="tableMaxHeight"
      :row-class-name="rowClassName"
      :row-style="{cursor: 'pointer'}"
      fit
      element-loading-text="加载中..."
      header-cell-class-name="dynamic-edit-table-cell"
      hightlight-current-row
      @cell-click="cellClick"
      @row-click="toEdit"
      @select="selectTable"
      @select-all="selectTable"
      @selection-change="onSelectChange"
    >
      <EmptyPlaceholder slot="empty" :empty-text="emptyText" is-border mode="table" style="padding-bottom: 0;" />
      <el-table-column
        v-if="showSelection"
        align="center"
        type="selection"
        width="50"
      />
      <template v-for="(settingItem, index) in listSetting">
        <el-table-column
          :key="index"
          :label="settingItem.label"
          v-bind="settingItem.prop || {}"
          :width="settingItem.width || '100px'"
          align="left">
          <template slot="header" slot-scope="scope">
            <div class="dynamic-table-header">
              <span v-if="settingItem.isRequired" style="color: #f56c6c;margin-right:4px;">*</span>
              <span class="label">{{ scope.column.label }}</span>
            </div>
          </template>
          <template slot-scope="scope">
            <!-- 编辑模式 -->
            <div
              v-if="!scope.row.onlyRead"
              :class="{
                'isError': errorIds.includes(`${settingItem.keyword}${(curPage-1)*perPage + scope.$index}`),
                'isSelect': selectActive === `${settingItem.keyword}$${scope.$index}` && isFill
              }"
              @click.stop="setSelectActive((settingItem.disabled)?'':`${settingItem.keyword}$${scope.$index}`, true)"
            >
              <!-- 输入框：字符串 -->
              <template v-if="settingItem.type === 'inputText'">
                <el-input
                  v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                  v-model="scope.row[settingItem.keyword]"
                  :disabled="settingItem.disabled || scope.row.disable"
                  :maxlength="!settingItem.dynamicFunction?settingItem.maxlength || 50 : settingItem.dynamicFunction(scope.row, settingItem).maxlength"
                  :placeholder="!settingItem.dynamicFunction ? (scope.row.disable ? settingItem.defaultEmpty : settingItem.placeholder) || settingItem.label : settingItem.dynamicFunction(scope.row, settingItem).placeholder"
                  size="small"
                  type="text"
                  class="edit-table-input-text"
                  clearable
                  @input="textInput"
                />
              </template>
              <!-- 输入框：数字 -->
              <div v-else-if="settingItem.type === 'inputNumber'" :class="`edit-input-number-${settingItem.keyword}`" style="position:relative;">
                <el-input
                  v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                  v-model="scope.row[settingItem.keyword]"
                  :placeholder="(scope.row.disable ? settingItem.defaultEmpty : settingItem.placeholder) || settingItem.label"
                  :disabled="settingItem.disabled || scope.row.disable || rateDisable(scope.row, settingItem)"
                  :oninput="`
                    if(value>${settingItem.maxnumber || 999999999999}) {value=${settingItem.maxnumber || 999999999999}}
                    else if(${settingItem.isPositiveNumber} && value < 0) {value = null}
                    `"
                  type="number"
                  size="small"
                  @change="numberInputChange(scope.row, settingItem.keyword)"
                  @mousewheel.native.prevent
                />
                <span v-if="settingItem.unit" class="unit">{{ settingItem.unit }}</span>
              </div>
              <!-- 下拉滚动分页 -->
              <selectWithUserLoad
                v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                v-else-if="settingItem.type === 'scrollSelect' || (settingItem.type === 'resourceOrProject' && scope.row.energyType === '项目订单')"
                v-model="scope.row[settingItem.scrollKeyword || settingItem.keyword]"
                :ref="`select_${scope.row.orderPrivateId}_${settingItem.keyword}_ref`"
                :default-list="settingItem.options || scope.row[`${settingItem.keyword}_dynamic_options`] || []"
                :loadmore-method="settingItem.loadmoreMethod"
                :extend-params="settingItem.extendParams"
                :multiple="settingItem.multiple"
                :disabled="settingItem.disabled || exitEmptyDisable(scope.row, settingItem)"
                :key-name="settingItem.scrollKeyName || settingItem.keyName ? settingItem.scrollKeyName || settingItem.keyName : 'id'"
                :label-name="settingItem.scrollLabelName || settingItem.labelName ? settingItem.scrollLabelName || settingItem.labelName : 'name'"
                :value-type="settingItem.valueType ? settingItem.valueType : ''"
                :popper-append-to-body="appendToBody"
                :is-dynamic-load="settingItem.isDynamicLoad"
                :hide-select-list="getHideList(scope, settingItem)"
                :clearable="!settingItem.notShowClear"
                :foot="settingItem.foot"
                :show-check-user="settingItem.showCheckUser"
                :foot-tag="settingItem.footTag"
                visible-change-data
                filterable
                @clear="clear(scope.row, settingItem)"
                @focus="selectFocus(scope.row, settingItem)"
                @change="selectChange($event, scope.row, {...settingItem,...{keyword: settingItem.scrollKeyword || settingItem.keyword}})"
                @changeMethod="scrollSelectChangeMethod($event, scope.row, {...settingItem,...{keyword: settingItem.scrollKeyword || settingItem.keyword}})"
              />
              <!-- 下拉选项 -->
              <selectWithoutHttp
                v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                v-else-if="settingItem.type === 'select' || (settingItem.type === 'resourceOrProject' && scope.row.energyType !== '账号')"
                v-model="scope.row[settingItem.selectKeyword || settingItem.keyword]"
                :list-data="settingItem.options || getSelectOptions(scope.row, settingItem)"
                :multiple="false"
                :disabled="settingItem.disabled || exitEmptyDisable(scope.row, settingItem) || fitKeyDisabled(scope.row, settingItem)"
                :key-name="settingItem.selectKeyName || settingItem.keyName ? settingItem.selectKeyName || settingItem.keyName : 'id'"
                :label-name="settingItem.selectLabelName || settingItem.labelName ? settingItem.selectLabelName || settingItem.labelName : 'name'"
                :popper-append-to-body="appendToBody"
                :tip-key="settingItem.tipKey"
                class="select"
                filterable
                clearable
                @selectWithoutHttpFocus="selectWithoutHttpFocus(scope.row, {...settingItem,...{keyword: settingItem.selectKeyword || settingItem.keyword}})"
                @visible-changes="setSelectActive(settingItem.disabled?'':`${settingItem.keyword}$${scope.$index}`, $event, settingItem.disabled)"
                @change="selectChange($event, scope.row, {...settingItem,...{keyword: settingItem.selectKeyword || settingItem.keyword}})"
              />
              <!-- 缓存下拉加载 -->
              <cacheSelect
                v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                v-else-if="settingItem.keyword==='operatorId' || (settingItem.type === 'resourceOrProject' && (scope.row.energyType === '账号' || !scope.row.energyType))"
                v-model="scope.row[settingItem.keyword]"
                :show-list-data="settingItem.keyword === 'operatorId' ? allUserList : scope.row.platformId? resourceData[`${currentKey}`] : []"
                :ref="`select_${scope.row.orderPrivateId}_${settingItem.keyword}_ref`"
                :multiple="settingItem.multiple"
                :default-list="settingItem.options || scope.row[`${settingItem.keyword}_dynamic_options`] || []"
                :disabled="settingItem.disabled || exitEmptyDisable(scope.row, settingItem)"
                :key-name="settingItem.keyName ? settingItem.keyName : 'id'"
                :label-name="settingItem.labelName ? settingItem.labelName : 'name'"
                :popper-append-to-body="appendToBody"
                :hide-select-list="settingItem.multiple ? scope.row.associateList : [{[settingItem.keyName]: scope.row[settingItem.keyword], [settingItem.labelName]: (scope.row[settingItem.labelName] || '')}]"
                :is-dynamic-load="settingItem.isDynamicLoad"
                :area-name="settingItem.labelName"
                :data-loading="dataLoading"
                :has-platform = "!!scope.row.platformId"
                visible-change-data
                filterable
                clearable
                @focus="selectFocus(scope.row, settingItem)"
                @change="selectChange($event, scope.row, settingItem)"
                @changeMethod="scrollSelectChangeMethod($event, scope.row, settingItem)"
              />
              <!-- 多级下拉 -->
              <el-cascader
                v-else-if="settingItem.type === 'cascader'"
                v-model="scope.row[settingItem.keyword]"
                :options="settingItem.options"
                :show-all-levels="settingItem.showAllLevels !== false"
                :props="{
                  value: settingItem.keyName || 'value',
                  label: settingItem.labelName || 'label',
                  emitPath: settingItem.emitPath !== false,
                  multiple: !!settingItem.multiple,
                  checkStrictly: !!settingItem.checkStrictly
                }"
                collapse-tags
                filterable
                class="cascader-tag"
                style="width: 100%"
                popper-class="dynamic-order-cascader-popper-class"
                @change="selectChange($event, scope.row, settingItem)" />
              <!-- 日期选择 -->
              <el-date-picker
                v-cellFocus="{label:settingItem.label,currentLabel:currentLabel}"
                v-else-if="settingItem.type === 'datepicker'"
                v-model="scope.row[settingItem.keyword]"
                :clearable="true"
                :editable="false"
                :append-to-body="appendToBody"
                :type="settingItem.pickerType?settingItem.pickerType:'date'"
                :format="settingItem.pickerFormat?settingItem.pickerFormat:'yyyy/MM/dd'"
                :placeholder="settingItem.placeholder?settingItem.placeholder:'选择日期'"
                :disabled="settingItem.disabled"
                value-format="timestamp"
                size="small"
                style="width:100%;"
                @change="datePickerChange($event, scope.row, settingItem)" />
            </div>
            <!-- 只读模式 -->
            <div
              v-else
              :style="settingItem.showType==='price'?{justifyContent: 'flex-end'}:''"
              :class="{
                'isError isRead': errorIds.includes(`${settingItem.keyword}${(curPage-1)*perPage + scope.$index}`),
                'isSelect': selectActive === `${settingItem.keyword}$${scope.$index}` && isFill
              }"
              class="read-content">
              <PriceColumn v-if="settingItem.showType==='price'" :real-val="scope.row[settingItem.keyword]" :price="scope.row[settingItem.keyword]" />
              <span v-else-if="settingItem.type === 'datepicker'">{{ scope.row[settingItem.keyword] | format(settingItem.formatStr?settingItem.formatStr:'YYYY/MM/DD') }}</span>
              <span v-else-if="settingItem.renderType === 'filter'">{{ dataFilter(scope.row[settingItem.keyword], settingItem) }}</span>
              <div v-else-if="settingItem.formatTime">
                {{ scope.row[settingItem.keyword] | format('YYYY/MM/DD HH:mm:ss') }}
              </div>
              <div v-else-if="settingItem.multiple" class="overflow">
                <ToolTip :content="formatTag(scope.row[settingItem.keyword], settingItem.labelName)" />
              </div>
              <div v-else-if="settingItem.type === 'resourceOrProject'">
                <ToolTip :content="getRenderContent(scope.row)"/>
              </div>
              <template v-else>
                <div v-if="scope.row[settingItem.renderKeyword || settingItem.keyword] || scope.row[settingItem.renderKeyword || settingItem.keyword] === 0" class="item" placement="top" effect="dark">
                  <div class="overflow">
                    {{ scope.row[settingItem.renderKeyword || settingItem.keyword] }}
                    <span v-if="settingItem.unit">{{ settingItem.unit }}</span>
                  </div>
                </div>
                <div v-else>--</div>
              </template>
            </div>
          </template>
        </el-table-column>
      </template>
      <el-table-column
        :width="150"
        :fixed="fixed"
        align="left"
        label="操作">
        <template slot-scope="scope">
          <div style="display:flex; padding:0 10px" @click.stop="()=>{}">
            <el-tooltip v-if="firstHover" placement="top" effect="dark" >
              <div slot="content" style="max-width: 200px">点击对应区域即可编辑</div>
              <el-button type="text" @click="toEdit(scope.row)"><span style="font-size:14px;" @mouseleave="()=>{firstHover=false}" >编辑</span></el-button>
            </el-tooltip>
            <el-button v-else type="text" @click="toEdit(scope.row)"><span style="font-size:14px;" @mouseleave="()=>{firstHover=false}" >编辑</span></el-button>
            <el-button v-if="showCopyBtn" type="text" @click="copy(scope.row)"><span style="font-size:14px;">复制</span></el-button>
            <el-button :disabled="canEmpty ? false : value.length === 1" type="text" @click="deleteItem(scope.row, scope.$index)"><span style="font-size:14px;">删除</span></el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <empty-placeholder v-else :empty-text="emptyText" :empty-img="emptyDataIcon" image-size="100px" style="margin-bottom: 24px" />
    <div v-if="isEdit && showAddBtn" style="margin-top:10px;">
      <div :style="addBtnStyle" class="add-btn" @click="addValue">{{ btnText }}<i v-if="showAddIcon" class="el-icon-plus" /> </div>
    </div>
  </div>
</template>

<script>
/**
 * 动态编辑表格：listSetting的属性说明
 *
 * @param {string}  label   名称
 * @param {string}  keyword 字段
 * @param {string}  width   宽度
 * @param {boolean}  isRequired   必填
 * @param {string}  type    编辑状态时的类型：inputText(字符串输入框)、inputNumber(数字输入框)、select(不能下拉加载的下拉框)
 * @param {array}  options  下拉选项
 * @param {string}  renderType  只读模式渲染内容方式：filter(根据options列表渲染名称)
 * @param {boolean}  onlyRead  非输入框，且白色背景，鼠标不禁止
 * @param {boolean}  formatTime  时间戳，且需格式化时间
 * @param {string}  importApi  上传组件的文件上传路径
 * @param {boolean}  uploadIcon  上传组件是否需要icon
 * @param {string}  formatStr  时间组件的格式化字符串
 * @param {string}  placeholder  占位提示字符
 * @param {string}  pickerType  时间选择组件类型
 * @param {string}  pickerFormat  时间选择组件格式化字符串
 */
import selectWithUserLoad from '@/components/Common/selectWithUserLoad';
import selectWithoutHttp from '@/components/Common/selectWithoutHttp';
import cacheSelect from './cacheSelect';
import EmptyPlaceholder from '@/components/Common/emptyPlaceholder';
import uploadFile from '@/components/Common/uploadFile';
import emptyDataIcon from '@/assets/empty-data-icon.png';
import { formatTag } from '@/filters/dept';
import { format } from '@/filters/date';
import tableSelections from '@/mixins/tableSelections';
import { hasRouteAuth } from '@/utils/permission';
import { showModal } from '@/utils/message';
import { getUserList } from '@/api/user';// 3.0.1数据缓存
import { getResourceList } from '@/api/resource';

export default {
  components: { selectWithoutHttp, cacheSelect, EmptyPlaceholder, uploadFile, selectWithUserLoad },
  filters: {
    format
  },
  directives: {
    cellFocus: {
      inserted(el, binding) {
        if (binding.value.label === binding.value.currentLabel) {
          el.querySelector('.el-input__inner').focus();
        }
      }
    }
  },
  mixins: [tableSelections],
  model: {
    prop: 'value',
    event: 'changeValue'
  },
  props: {
    value: {
      type: Array,
      default: () => {
        return [];
      }
    },
    listData: {
      type: Array,
      default: () => {
        return [];
      }
    },
    listDataCount: { // 有数据总条数，则分页为后端分页，前端请求数据
      type: Number,
      default: 0
    },
    listSetting: {
      type: Array,
      default: () => {
        return [];
      }
    },
    btnText: {
      type: String,
      default: ''
    },
    addBtnStyle: {
      type: Object,
      default: null
    },
    showSelection: {
      type: Boolean,
      default: false
    },
    isEdit: {
      type: Boolean,
      default: false
    },
    showDeleteBtn: {
      type: Boolean,
      default: true
    },
    showAddBtn: {
      type: Boolean,
      default: true
    },
    showCopyBtn: {
      type: Boolean,
      default: true
    },
    isFill: { // 填充功能
      type: Boolean,
      default: false
    },
    appendToBody: { // 填充功能
      type: Boolean,
      default: true
    },
    canEmpty: { // 是否允许为空
      type: Boolean,
      default: false
    },
    showAddIcon: {
      type: Boolean,
      default: true
    },
    defaultParams: {
      type: Object,
      default: () => {
        return {};
      }
    },
    specialColumn: {
      type: Array,
      default: () => []
    },
    orderPrivateId: { // 手动添加订单标识符
      type: Number,
      default: 1
    },
    disableValidKeys: {
      type: Array,
      default: () => []
    },
    hasBorder: { // 表格是否需要边框
      type: Boolean,
      default: true
    },
    emptyText: { // 无数据提示语
      type: String,
      default: '暂无数据'
    },
    showTableHeader: { // 没有数据时是否展示表头
      type: Boolean,
      default: false
    },
    tableMaxHeight: { // 列表最大高度
      type: [String, Number],
      default: null
    },
    nonCopyKey: { // 复制行时过滤项
      type: Array,
      default: () => []
    },
    copyToNextRow: {
      type: Boolean,
      default: false
    },
    curPage: {
      type: Number,
      default: 1
    },
    perPage: {
      type: Number,
      default: 20
    },
    platformOption: {
      type: Array,
      default: () => []
    },
    fixed: {
      type: Boolean | String,
      default: 'right'
    }
  },
  data() {
    return {
      dataLoading: false,
      emptyDataIcon,
      errorIds: [],
      selectActive: '',
      selectedList: [], // 已选中的列表
      currentUser: this.$store.getters.userName, // 当前登录用户
      ids: '', // 列表当前选中的id
      idKey: 'orderPrivateId',
      tableRefName: 'dynamicEditRef',
      firstInitPanel: true,
      firstHover: true,
      currentLabel: '',
      allUserList: [],
      resourceData: {},
      currentKey: '', // 当前平台
      lastUpdateTime: {}, // 保存上次更新的时间
      updateTime: 10000// 单位，毫秒
    };
  },
  watch: {
    platformOption: {
      handler: function(newV) {
        if (newV) {
          this.initUpdateTime();
        }
      },
      immediate: true
    }
  },
  created() {
    this.initUserData();
  },
  methods: {
    hasRouteAuth,
    formatTag,
    async initUserData() {
      try {
        this.dataLoading = true;
        const userParams = {
          type: 1,
          page: 1,
          perPage: 0
        };
        const userRes = await getUserList(userParams);
        this.allUserList = userRes.data.items;
        this.dataLoading = false;
      } catch (err) {
        this.dataLoading = false;
        console.log(err);
      }
    },
    initUpdateTime() {
      this.platformOption.forEach(el => {
        this.lastUpdateTime[`${el.value}`] = new Date().getTime();
      });
      this.lastUpdateTime['人员'] = new Date().getTime();
    },
    validate() {
      // 验证必填项
      return new Promise((resolve, reject) => {
        const dataList = this.value;
        const requiredKeys = this.listSetting.map(i => {
          if (i.isRequired) {
            return i.keyword;
          }
        }).filter(i => !!i);

        let isOk = true;
        const errorIds = [];
        if (dataList && dataList.length > 0) {
          dataList.forEach((i, index) => {
            if (Array.isArray(requiredKeys) && requiredKeys.length) {
              const requiredKeyList = !i.customizeState && i.disable ? this.disableValidKeys : requiredKeys;
              requiredKeyList.forEach((j) => {
                let jkey = j;
                if (jkey === 'resourceId') {
                  if (i.energyType !== '账号')jkey = 'projectTypeId';
                  if (i.energyType === '项目订单')jkey = 'projectId';
                }
                if ((!i[jkey] && i[jkey] !== 0) || (Array.isArray(i[jkey]) && i[jkey].length === 0)) {
                  errorIds.push(`${j}${index}`);
                  isOk = false;
                }
              });
            }

            i.extendRequiredKeys = i.energyType === '项目' ? ['remark'] : [];
            if (Array.isArray(i.extendRequiredKeys) && i.extendRequiredKeys.length) {
              i.extendRequiredKeys.forEach((k) => {
                if ((!i[k] && i[k] !== 0) || (Array.isArray(i[k]) && i[k].length === 0)) {
                  errorIds.push(`${k}${index}`);
                  isOk = false;
                }
              });
            }
            if (i._required) {
              if ((!i[i._required] && i[i._required] !== 0) || JSON.stringify(i[i._required]) === '{}') {
                errorIds.push(`${i._required}${index}`);
                isOk = false;
              }
            }
          });
        }
        this.errorIds = errorIds;
        if (isOk) {
          resolve(true);
        } else {
          reject(false);
        }
      });
    },
    selectFocus(rowData, settingItem) {
      // 多选时防止每次选中都重新请求接口
      if (!this.firstInitPanel && settingItem.multiple) {
        this.firstInitPanel = true;
        return;
      }
      this.$emit('selectFocus', settingItem.keyword, rowData);
    },
    selectWithoutHttpFocus(rowData, settingItem) {
      if (!rowData.projectTypeId && rowData.projectTypeId !== 0) return;
      if (settingItem.type === 'resourceOrProject' && !['账号', '项目订单'].includes(rowData.energyType)) {
        const options = this.getSelectOptions(rowData, settingItem);
        if (!options.find(item => item.id === rowData.projectTypeId)) {
          rowData.projectTypeId = '';
          rowData.projectType = '';
          this.$message.warning('当前选项无法适用该精力类型，请重新选择');
          this.selectChange(null, rowData, settingItem);
        }
      }
    },
    selectChange(e, item, settingItem) {
      settingItem.multiple && (this.firstInitPanel = false);
      if (item.isAuto && settingItem.linkField) {
        const data = settingItem.options.find(i => i.id === e);
        if (data)item[settingItem.linkField] = data[settingItem.linkField];
      }
      this.$emit('selectChange', { item: item, key: settingItem.keyword });
      this.changeValue();
      if (settingItem.keyword === 'platformId') { // 新增时获取数据
        this.currentKey = item.orderPlatform;
        this.cacheResource(e);
      }
    },
    scrollSelectChangeMethod(data, row, settingItem) {
      if (data) {
        const rowData = JSON.parse(JSON.stringify(data));
        rowData.orderPrivateId = row.orderPrivateId;
        this.$emit('scrollSelectChange', settingItem.keyword, rowData);
      } else {
        this.$emit('scrollSelectClear', settingItem.keyword, row);
      }
    },
    clear(item, settingItem) {
      this.$emit('clear', { item: item, key: settingItem.keyword });
      this.changeValue();
    },
    datePickerChange(value, rowData, settingItem) {
      this.changeValue();
      this.$emit('datePickerChange', { item: rowData, key: settingItem.keyword });
    },
    changeValue(value = null) {
      this.$emit('changeValue', value || this.value);
      this.errorIds = []; // 重制红框
      this.$nextTick(() => {
        this.$emit('onSelectChange', this.multipleSelectionAll);
      });
    },
    changeInputNumberData(item, key) {
      this.$emit('changeInputNumberData', { item: item, key: key });
    },
    dataFilter(rowData, settingItem) {
      if ((rowData || rowData === 0) && settingItem && settingItem.options) {
        const obj = settingItem.options.find(i => Number(i.id) === Number(rowData));
        return obj ? obj.name : '--';
      }
      return '--';
    },
    textInput() {
      this.changeValue();
    },
    numberInputChange(row, key) {
      if (row[key]) row[key] = Number(row[key]).toFixed(2);
      this.changeValue();
      this.changeInputNumberData(row, key);
    },
    // 多选
    tableSelectionChange(e) {
      this.ids = e.map(item => item[this.idKey]).join();
    },
    // 自定义翻页
    handleData(tableData) {
      const pageData = tableData && tableData.slice((this.curPage - 1) * this.perPage, this.curPage * this.perPage) || [];
      this.setSelectRow && this.setSelectRow(pageData);
      return pageData;
    },
    addValue(isFlashback = false) {
      let params = {};
      if (this.defaultParams) {
        params = { ...this.defaultParams };
      }
      this.listSetting.forEach(i => {
        if (i.default || i.default === 0) {
          params[i.keyword] = i.default;
        }
      });
      this.$emit('toReadModel');// 取消编辑态
      params.onlyRead = false;
      params.orderPrivateId = this.orderPrivateId + 1;
      this.$emit('orderPrivateIdChange', this.orderPrivateId + 1);
      isFlashback ? this.value.unshift(params) : this.value.push(params);
      this.changeValue();
    },
    deleteItem(item, index) {
      // item.isAdd 新增行的删除，不需要弹框提示
      if (this.appendToBody && !item.isAdd) {
        const tip = '是否确定删除？';
        showModal(tip, '', {
          center: true,
          showClose: true
        }).then(() => {
          if (this.curPage > 1 && this.perPage) {
            index += (this.curPage - 1) * this.perPage;
          }
          this.value.splice(index, 1);
          this.changeValue();
          this.$emit('onRowDel', item);
        });
      } else {
        this.value.splice(index, 1);
        this.changeValue();
      }
    },
    rateDisable(row = {}, settingItem) {
      if (settingItem.keyword === 'allocationRatio') {
        if (!['账号', '项目订单'].includes(row.energyType) && !row.projectType) return true;
      }
      return false;
    },
    fitKeyDisabled(row = {}, settingItem) {
      if (!settingItem.fitKeyDisabled) return false;
      const { key, value } = settingItem.fitKeyDisabled;
      return row[key] === value;
    },
    exitEmptyDisable(row = {}, settingItem) {
      if (!settingItem.associatedKeys) return false;
      const keys = settingItem.associatedKeys || [];
      let isEmpty = true;
      keys.forEach(key => {
        if (row[key]) {
          isEmpty = false;
        }
      });
      return isEmpty;
    },
    copy(item) {
      const copyData = JSON.parse(JSON.stringify(item));
      if (copyData.id || copyData.id === 0) delete copyData.id;
      copyData.disable && delete copyData.disable;
      copyData.customizeState = true;
      copyData.orderPrivateId = this.orderPrivateId + 1;
      this.nonCopyKey.forEach(key => {
        delete copyData[key];
      });
      this.$emit('orderPrivateIdChange', this.orderPrivateId + 1);
      this.$emit('toReadModel');
      this.$set(copyData, 'onlyRead', false);
      if (this.copyToNextRow) {
        const rowIndex = this.value.findIndex(valueItem => valueItem.orderPrivateId === item.orderPrivateId);
        this.value.splice(rowIndex + 1, 0, copyData);
      } else {
        this.value.push(copyData);
      }
      this.changeValue();
    },
    // 编辑某行
    toEdit(row) {
      this.$emit('toReadModel');
      this.$set(row, 'onlyRead', false);
      this.$forceUpdate();
    },
    // 点击单元格获取焦点
    cellClick(row, column, cell, event) {
      this.currentLabel = column.label;
      this.currentKey = row.orderPlatform;
      if (column.label === '账号/项目名称' && row.energyType === '账号') {
        this.cacheResource(row.platformId);// 第一次点击平台进行数据缓存
      }
      this.updateCache(this.updateTime, column.label, row);
    },
    updateCache(time = 5000, label = '', row = {}) {
      const nowTime = new Date().getTime();
      const _this = this;
      if (label === '下单平台' && nowTime - this.lastUpdateTime[`${row.orderPlatform}`] > time) {
        this.lastUpdateTime[`${row.orderPlatform}`] = nowTime;
        setTimeout(function() {
          _this.cacheResource(row.platformId);// 更新数据
        }, 0);
      }
      if (label === '运营人员' && nowTime - this.lastUpdateTime[`人员`] > time) {
        this.lastUpdateTime[`人员`] = nowTime;
        setTimeout(function() {
          _this.initUserData();
        }, 0);
      }
    },
    // 进行平台下账号数据的缓存,第一次缓存
    async cacheResource(id) {
      if (this.resourceData[`${this.currentKey}`] || !id) {
        return;
      }
      try {
        this.dataLoading = true;
        const keyName = this.platformOption.filter(el => el.id === id)[0].value;
        this.currentKey = keyName;// 切换数据源
        if (this.resourceData[`${keyName}`]) {
          return;
        }
        this.resourceData[`${keyName}`] = [];
        const params = {
          page: 1,
          perPage: 0,
          platformId: id,
          type: 1,
          options: encodeURIComponent(JSON.stringify([]))
        };
        const res = await getResourceList(params);
        this.resourceData[`${keyName}`] = res.data.items;
        this.dataLoading = false;
      } catch (err) {
        this.dataLoading = false;
        console.log(err);
      }
    },
    rowClassName(data) {
      return !data.row.onlyRead ? 'edit-mode' : 'read-mode';
    },
    setSelectActive(name, isSet) {
      if (isSet) this.selectActive = name;
    },
    handleChange(val) {
      // console.log(val);
    },
    // 表格勾选中
    onSelectChange(data) {
      this.selectedList = data;
      this.$nextTick(() => {
        this.$emit('onSelectChange', this.multipleSelectionAll);
      });
    },
    getHideList(scope, settingItem) {
      if (settingItem.multiple) {
        return scope.row.associateList;
      }
      if (scope.row[`${settingItem.keyword}_hideList`]) {
        return scope.row[`${settingItem.keyword}_hideList`];
      }
      if (settingItem.valueType === 'object') {
        return [{ ...scope.row[settingItem.keyword] }];
      }
      const item = { [settingItem.scrollKeyName || settingItem.keyName]: scope.row[settingItem.scrollKeyword || settingItem.keyword], [settingItem.scrollLabelName || settingItem.labelName]: (scope.row[settingItem.scrollLabelName || settingItem.labelName] || '') };
      if (settingItem.foot) {
        item[settingItem.foot] = scope.row[settingItem.foot];
      }
      return [item];
    },
    getSelectOptions(row, { options = [], projectTypeOptions = [], type }) {
      if (type !== 'resourceOrProject') return options;
      const result = [];
      projectTypeOptions.forEach(item => {
        const applicativeTypesList = item.applicativeTypesList || [];
        if (applicativeTypesList.includes(row.energyTypeId)) {
          result.push(item);
        }
      });
      return result;
    },
    getRenderContent(row) {
      const energyType = row.energyType;
      return {
        '账号': row['resourceName'] || '--',
        '项目订单': `${row['projectName'] ? `${row['projectName']}(${row['projectNum']})` : '--'}`
      }[energyType] || row['projectType'] || '--';
    }
  }
};
</script>
<style lang="scss">
.dynamic-order-cascader-popper-class {
  &::v-deep {
    .el-input {
      width: 250px;
    }
    .el-cascader-panel .el-cascader-menu__wrap {
      height: unset !important;
      max-height: 204px;
    }
  }
}
.edit-mode,.read-mode{
  td {
    height: 49px !important;
    padding: 0 !important;
  }
  .cell:first-child{
    padding: 0 !important;
  }
}
.edit-mode {
  .el-select__caret {
    color: #333 !important;
  }
  .cell {
    padding: 0 ;
    .el-input__inner {
      height: 49px !important;
      border-radius: 0 !important;
      border-color: transparent !important;
    }
  }
}
.read-mode{
  td:first-child{
    display: flex;
    justify-content: center;
  }
  .cell {
    display: flex;
    align-items: center;
    padding: 0 ;
    height: 49px !important;
  }
}
</style>
<style lang="scss" scoped>
.cascader-tag {
  &::v-deep {
    .el-tag {
      color: #406eff;
      background: #eff3fb;
    }
  }
}
.read-content {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  width: 100%;
  height: 100%;
  padding-left: 8px;
  .overflow {
    display: inline;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}
.custom-column {
  width: 100%;
  background-color: #f5f7fa;
  height: 56px;
  cursor: not-allowed;
  padding-left: 15px;
  padding-right: 15px;
  display: flex;
  align-items: center;
}
.read-content-operate{
  width: 100%;
}
.whiteBg {
  background-color: #fff;
  cursor: auto;
}
.add-btn {
  width: 100%;
  height: 56px;
  border: 1px dashed #406EFF;
  border-radius: 4px;
  font-size: 16px;
  font-weight: 500;
  color: #406EFF;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.unit {
  position: absolute;
  top: 50%;
  right: 5px;
  user-select: none;
  transform: translate(0, -50%);
}
.dynamic-container {
  margin-top: 15px;
  .dynamic-table-header {
    display:flex;align-items:center;
    .label {
      color: #141C3D;
      font-weight: 600;
    }
  }
  &::v-deep {
    .el-cascader-menu__wrap {
      height: unset !important;
      max-height: 204px !important;
    }
    .dynamic-edit-table-cell {
      background: #F9F9F9;
    }
    .el-table__fixed {
      &::before {
        background-color: transparent;
      }
    }
    .el-table__fixed-right {
      &::before {
        background-color: transparent;
      }
    }
    .el-table--border::after {
      background-color: transparent;
    }
    .el-table {
      border-color: transparent;
      &::before {
        background-color: transparent;
      }
      thead {
        th.dynamic-edit-table-cell {
          &:last-child {
            border-right-color: transparent;
          }
          &:nth-last-child(2) {
            border-right-color: transparent;
          }
        }
      }
      .is-scrolling-none {
        .el-table__empty-block {
          width: 100% !important;
        }
      }
      .el-table__empty-text {
        width: 100%;
      }
      tbody {
        tr {
          td:last-child {
            border-right-color: transparent;
          }
        }
        .el-table__row {
          &:last-child {
            td {
              border-bottom: 1px solid #EBEEF5;
            }
          }
        }
      }
    }
    .el-date-table,.el-year-table,.el-month-table {
      th {
        border-right: none;
      }
    }
    .el-date-table td {
      padding: 4px 0 !important; border: none !important;
    }
    .el-year-table td {
      padding: 20px 3px !important; border: none !important;
    }
    .el-month-table td {
      padding: 8px 0 !important; border: none !important;
    }
  }
  .border-left {
    position: relative;
    padding-left:6px;
    margin-left: 6px;
    &::before {
      content: '';
      position: absolute;
      left: 0;
      top: 50%;
      margin-top: -7px;
      width: 1px;
      background: #ddd;
      height: 14px;
    }
  }
}
.select-inner {
  border: 1px solid transparent;
  height: 56px;
  display: flex;
  align-items: center;
}
.isSelect {
  &::v-deep {
    .el-input__inner {
      border-color: #406EFF !important;
    }
  }
  .select-inner {
    border-color: #406EFF !important;
  }
}
.isRead{
  border:1px solid red;
}
.isError {
  &::v-deep {
    .el-table__row{
      td{
        border:1px solid red !important;
      }
    }
    .el-input__inner {
      border-color: red !important;
    }
    .attachment-container{
      border:1px solid red;
    }
  }
}
</style>
